package com.kymatrix.kycarbon.xsmd.common.business.security.filter;

import cn.hutool.core.util.StrUtil;
import com.kymatrix.kycarbon.xsmd.common.business.common.ResultResp;
import com.kymatrix.kycarbon.xsmd.common.util.ServletUtils;
import com.kymatrix.kycarbon.xsmd.common.springsecurity.LoginUser;
import com.kymatrix.kycarbon.xsmd.common.springsecurity.SecurityUtils;
import com.kymatrix.kycarbon.xsmd.common.springsecurity.api.OAuth2TokenApi;
import com.kymatrix.kycarbon.xsmd.common.springsecurity.config.SecurityProperties;
import com.kymatrix.kycarbon.xsmd.common.springsecurity.filter.ITokenAuthenticationFilter;
import java.io.IOException;
import java.util.List;
import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;

/**
 * Token 过滤器，验证 token 的有效性
 */
@Slf4j
@Component
public class TokenAuthenticationFilter implements ITokenAuthenticationFilter {

    private final AntPathMatcher pathMatcher = new AntPathMatcher();

    @Resource
    private SecurityProperties securityProperties;

    @Resource
    private OAuth2TokenApi oauth2TokenApi;

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
        List<String> permitAllUrls = securityProperties.getPermitAllUrls();
        for (String url : permitAllUrls) {
            if (pathMatcher.match(url, req.getRequestURI())) {
                chain.doFilter(request, response);
                return;
            }
        }

        String token = SecurityUtils.getToken(req, securityProperties.getTokenHeader());
        if (StrUtil.isEmpty(token)) {
            ServletUtils.writeJSON(resp, ResultResp.authError("账号未登录"));
            return;
        }
        try {
            LoginUser loginUser = oauth2TokenApi.checkAccessToken(token);
            if (loginUser == null) {
                ServletUtils.writeJSON(resp, ResultResp.authError("token异常"));
                return;
            }
            SecurityUtils.setLoginUser(loginUser, req);
            // 继续过滤链
            chain.doFilter(request, response);
        } catch (Exception ex) {
            log.error("验证token出现异常", ex);
            ServletUtils.writeJSON(resp, ResultResp.authError("token异常"));
        }
        
    }
}
